package com.sunther.document.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunther.document.dao.RoleDao;
import com.sunther.document.entity.*;
import com.sunther.document.service.RoleService;
import com.sunther.document.service.RoleTagMiddleService;
import com.sunther.document.service.RoleTagService;
import com.sunther.idb.common.util.WebResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author csb
 * @description: TODO
 * @date 2023/5/15 11:51
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleDao, RoleEntity> implements RoleService {

    @Autowired
    private RoleTagService roleTagService;

    @Autowired
    private RoleTagMiddleService roleTagMiddleService;

    @Autowired
    private RoleDao roleDao;

    @Override
    public Map<Integer, String> getAllRoleNameMap() {
        List<RoleEntity> list = list();
        Map<Integer, String> map = list.stream().collect(Collectors.toMap(RoleEntity::getId, RoleEntity::getName));
        return map;
    }

    @Override
    public List<RoleEntityVo> listAndRoleTag() {

        List<RoleEntity> list = list();
        ArrayList<RoleEntityVo> vos = new ArrayList<>();
        list.stream().forEach(a -> {
            RoleEntityVo vo = new RoleEntityVo();
            BeanUtils.copyProperties(a, vo);
            vos.add(vo);
        });

        List<RoleByTagEntityVo> roleList = roleDao.getListByRole();

        Map<Integer, List<RoleByTagEntityVo>> collect = roleList.stream().collect(Collectors.groupingBy(RoleByTagEntityVo::getId));

        vos.stream().forEach(a -> {
            collect.forEach((k,v) -> {
                List<Tree<String>> trees = RoleByTagEntityVo.getTrees(v);
                if (a.getId().equals(k)){
                    a.setTreeList(trees);
                }
            });
        });

        return vos;
    }

    @Override
    public WebResult detail(Integer roleId) {

        RoleEntity byId = getById(roleId);

        List<Integer> tagIds = roleTagMiddleService.getTagIdByRoleId(roleId);
        Set<Integer> tagIdsNotOne = roleTagMiddleService.getTagIdByRoleIdNotLevelOne(roleId);

        List<RoleTagEntity> roleTagList = roleTagService.list();

        roleTagList.stream().filter(a -> tagIds.contains(a.getId())).forEach(b -> {
            b.setIfYes(true);
        });

        List<Tree<String>> treeList = RoleTagEntity.getTrees(roleTagList);

        RoleEntityVo vo = new RoleEntityVo();
        vo.setId(byId.getId());
        vo.setName(byId.getName());
        vo.setTreeList(treeList);

        HashMap<String, Object> map = new HashMap<>();
        map.put("role",tagIdsNotOne);

        return WebResult.success("操作成功",vo,map);
    }

    @Override
    public List<RoleEntity> listByKeyword(String keyword) {
        QueryWrapper<RoleEntity> wrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(keyword)){
            wrapper.like("name",keyword);
        }
        return this.list(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebResult saveData(RoleEntity data) {

        List<RoleTagEntity> treeList = data.getTreeList();

        List<RoleTagEntity> tagEntityList = getYesRoleTag(treeList);

        ArrayList<RoleTagMiddleEntity> middleEntities = new ArrayList<>();
        tagEntityList.stream().forEach(a -> {
            RoleTagMiddleEntity entity = new RoleTagMiddleEntity();
            entity.setRoleId(data.getId());
            entity.setRoleTagId(a.getId());
            middleEntities.add(entity);
        });

        saveOrUpdate(data);

        //1、先删除中间表数据
        QueryWrapper<RoleTagMiddleEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id",data.getId());
        roleTagMiddleService.remove(wrapper);
        //2、再保存
        roleTagMiddleService.saveBatch(middleEntities);

        return WebResult.success("操作成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebResult saveByIds(Set<Integer> tagIds, Integer roleId) {
        ArrayList<RoleTagMiddleEntity> middleEntities = new ArrayList<>();
        tagIds.stream().forEach(a -> {
            RoleTagMiddleEntity entity = new RoleTagMiddleEntity();
            entity.setRoleId(roleId);
            entity.setRoleTagId(a);
            middleEntities.add(entity);
        });

        //1、先删除中间表数据
        QueryWrapper<RoleTagMiddleEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id",roleId);
        roleTagMiddleService.remove(wrapper);
        //2、再保存
        roleTagMiddleService.saveBatch(middleEntities);
        return WebResult.success("保存成功");
    }

    @Override
    public WebResult getMenu(Integer roleId) {

        List<Integer> tagIds = roleTagMiddleService.getTagIdByRoleId(roleId);

        List<RoleTagEntity> roleTagList = roleTagService.list();

        roleTagList.stream().filter(a -> tagIds.contains(a.getId())).forEach(b -> {
            b.setIfYes(true);
        });

        return WebResult.success("获取成功",roleTagList);
    }

    private List<RoleTagEntity> getYesRoleTag(List<RoleTagEntity> trees) {
        ArrayList<RoleTagEntity> list = new ArrayList<>();
        trees.stream().forEach(a -> {
            recursionTree(a,list);
        });
        return list;
    }

    private void recursionTree(RoleTagEntity data , List<RoleTagEntity> list){

        if (data.isIfYes()){
            list.add(data);
        }
        if (null != data.getChildren() && data.getChildren().size() > 0){
            data.getChildren().stream().forEach(a -> {
                recursionTree(a,list);
            });
        }

    }

}
